package cj.utils.weixin;

import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.json.JSONObject;

import org.apache.http.protocol.HTTP;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import cj.utils.Constants;
import cj.utils.HttpClientUtil;
 
/**
 * 微信请求公共方法
 * @author Administrator
 *
 */
public class HttpsWenXinUtil {
 
    private static class TrustAnyTrustManager implements X509TrustManager {
 
        public void checkClientTrusted(X509Certificate[] chain, String authType)
                throws CertificateException {
        }
 
        public void checkServerTrusted(X509Certificate[] chain, String authType)
                throws CertificateException {
        }
 
        public X509Certificate[] getAcceptedIssuers() {
            return new X509Certificate[] {};
        }
    }
 
    private static class TrustAnyHostnameVerifier implements HostnameVerifier {
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    }
 
    /**
     * post方式请求服务器(https协议)
     * 
     * @param url
     *            请求地址
     * @param content
     *            参数
     * @param charset
     *            编码
     * @return
     * @throws NoSuchAlgorithmException
     * @throws KeyManagementException
     * @throws IOException
     */
    public static byte[] post(String url, String content, String charset)
            throws NoSuchAlgorithmException, KeyManagementException,
            IOException {
        SSLContext sc = SSLContext.getInstance("SSL");
        sc.init(null, new TrustManager[] { new TrustAnyTrustManager() },
                new java.security.SecureRandom());
 
        URL console = new URL(url);
        HttpsURLConnection conn = (HttpsURLConnection) console.openConnection();
        conn.setSSLSocketFactory(sc.getSocketFactory());
        conn.setHostnameVerifier(new TrustAnyHostnameVerifier());
        conn.setDoOutput(true);
        conn.connect();
        DataOutputStream out = new DataOutputStream(conn.getOutputStream());
        out.write(content.getBytes(charset));
        // 刷新、关闭
        out.flush();
        out.close();
        InputStream is = conn.getInputStream();
        if (is != null) {
            ByteArrayOutputStream outStream = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len = 0;
            while ((len = is.read(buffer)) != -1) {
                outStream.write(buffer, 0, len);
            }
            is.close();
            return outStream.toByteArray();
        }
        return null;
    }
    
    /**
	 * 组成XML返回消息
	 * @param toUserName
	 * @param fromUserName
	 * @param createTime
	 * @param msgType
	 * @param content
	 * @return
	 * @throws UnsupportedEncodingException 
	 */
	public static String respMessage(String toUserName,String fromUserName,String content,String messageType) throws UnsupportedEncodingException
	{
		String respMessage="<xml>"
				+ "<ToUserName><![CDATA["+toUserName+"]]></ToUserName>"
				+ "<FromUserName><![CDATA["+fromUserName+"]]></FromUserName>"
				+ "<CreateTime><![CDATA["+new Date().getTime()+"]]></CreateTime>"
				+ "<MsgType><![CDATA["+messageType+"]]></MsgType>"
				+ "<Content><![CDATA["+new String(content.getBytes("UTF-8"),"ISO8859_1")+"]]></Content>"
				+ "</xml>";
		return respMessage;
	}
	
	/**
	 * 回复消息
	 * 
	 * @param response
	 *            HttpServletResponse
	 * @param msg
	 *            回复的消息
	 */
	public static void print(HttpServletResponse response, String msg) {
		PrintWriter out = null;
		try {
			out = response.getWriter();
			out.print(msg);
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			out.close();
			out = null;
		}
	}
	
	/**
	 * 解析微信发来的请求（XML）
	 * 
	 * @param request
	 * @return Map
	 * @throws Exception
	 */
	public static Map<String, String> parseXml(HttpServletRequest request) throws Exception {
		// 将解析结果存储在HashMap中
		Map<String, String> map = new HashMap<String, String>();

		// 从request中取得输入流
		InputStream inputStream = request.getInputStream();
		// 读取输入流
		SAXReader reader = new SAXReader();
		Document document = reader.read(inputStream);
		// 得到xml根元素
		Element root = document.getRootElement();
		// 得到根元素的所有子节点
		
		@SuppressWarnings("unchecked")
		List<Element> elementList = root.elements();

		// 遍历所有子节点
		for (Element e : elementList){
			map.put(e.getName(), e.getText());
		}
		// 释放资源
		inputStream.close();
		inputStream = null;

		return map;
	}
 
    /**
	 * 返回访问微信接口结果
	 * @param requestUrl		请求URL
	 * @param begin_date		起始时间
	 * @param end_date			结束时间
	 * @return
	 * @throws KeyManagementException
	 * @throws NoSuchAlgorithmException
	 * @throws IOException
	 */
	public static JSONObject returnInvokeWeiXin(String appid,String secret,String requestUrl,String begin_date,String end_date) throws KeyManagementException, NoSuchAlgorithmException, IOException
	{
		String requestContent="{\"begin_date\":\""+begin_date+"\",\"end_date\":\""+end_date+"\"}";
		String access_token = initWeiXin(appid,secret);
		
		//请求远端微信Http接口
		byte[] xml = HttpsWenXinUtil.post(requestUrl+=access_token, requestContent, Constants.charset);
		return new JSONObject().fromObject(new String(xml, Constants.charset));
	}
	
	/**
	 * 获取access_token
	 * @return
	 */
	public static String initWeiXin(String appid,String secret)
	{
		//https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=wx5337b3924f31ca3e&secret=5f4df71fde9a297da01cac5c88941da1
		String xml = HttpClientUtil.get(Constants.weixinkey.weixinUrl+"&appid="+appid+"&secret="+secret, HTTP.UTF_8);
		JSONObject jsonObject = JSONObject.fromObject(xml); 
		String access_token = jsonObject.get("access_token").toString();
		return access_token;
	}
	
	/**
	 * 创建微信菜单
	 * @throws KeyManagementException
	 * @throws NoSuchAlgorithmException
	 * @throws IOException
	 */
	public static void createMenu() throws KeyManagementException, NoSuchAlgorithmException, IOException
	{
		String access_token = initWeiXin(Constants.weixinkey.AppID,Constants.weixinkey.AppSecret);
		String requestUrl = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=";
		
		//	http://marriage.cjrbjt.com/marriage/getweixincode
		String memuUrl_start = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxb8851d53461b983d&redirect_uri=http://marriage.haoyicn.cn/";
		String memuUrl_end ="&response_type=code&scope=snsapi_base&state=1#wechat_redirect";
		List<Map> buttons = new ArrayList<Map>();
		
		//---------------------------repButs3
		Map button3 = new HashMap();
		
		List<Map> sub_buttons3 = new ArrayList<Map>();
		
//		Map repBut33 = new HashMap();
//		repBut33.put("type", "view");
//		repBut33.put("name", "颁证仪式预约");
//		repBut33.put("url", memuUrl_start+"notes/tesheNotesCode"+memuUrl_end);
//		sub_buttons3.add(repBut33);
		
		Map repBut44 = new HashMap();
		repBut44.put("type", "view");
		repBut44.put("name", "城市留言板");
		repBut44.put("url", "http://wsqzgzb.cjn.cn/mobile/");
		sub_buttons3.add(repBut44);
		
		Map repBut31 = new HashMap();
		repBut31.put("type", "view");
		repBut31.put("name", "结婚预约");
		repBut31.put("url", memuUrl_start+"marryreg/marryAgreementCode"+memuUrl_end);
		sub_buttons3.add(repBut31);
		
//		Map repBut32 = new HashMap();
//		repBut32.put("type", "view");
//		repBut32.put("name", "其他预约须知");
//		repBut32.put("url", memuUrl_start+"notes/otherNotesCode"+memuUrl_end);
//		sub_buttons3.add(repBut32);
		
//		Map repBut33 = new HashMap();
//		repBut33.put("type", "view");
//		repBut33.put("name", "离婚预约");
//		repBut33.put("url", memuUrl_start+"notes/lihunNotesCode"+memuUrl_end);
//		sub_buttons3.add(repBut33);
		
		button3.put("name", "预约与留言");
		button3.put("sub_button", sub_buttons3);
		buttons.add(button3);
		
		//---------------------------repButs1
		Map button1 = new HashMap();
		
		List<Map> sub_buttons = new ArrayList<Map>();
//		Map repBut1 = new HashMap();
//		repBut1.put("type", "view");
//		repBut1.put("name", "颁证仪式预约");
//		repBut1.put("url", memuUrl_start+"marryreg/crtCode"+memuUrl_end);
//		sub_buttons.add(repBut1);
		
//		Map repBut2 = new HashMap();
//		repBut2.put("type", "view");
//		repBut2.put("name", "我要预约");
//		repBut2.put("url", memuUrl_start+"notes/myBespeak"+memuUrl_end);
//		sub_buttons.add(repBut2);
		
/*		Map repBut3 = new HashMap();
		repBut3.put("type", "view");
		repBut3.put("name", "颁证视频案例");
		repBut3.put("url", memuUrl_start+"videos/videoLis"+memuUrl_end);
		sub_buttons.add(repBut3);*/
		
//		Map repBut5 = new HashMap();
//		repBut5.put("type", "view");
//		repBut5.put("name", "我要上头条");
//		repBut5.put("url", "http://marriagewx.cjrbjt.com/Public/index.php");
//		sub_buttons.add(repBut5);
		
//		Map repBut6 = new HashMap();
//		repBut6.put("type", "view");
//		repBut6.put("name", "我的头条");
//		repBut6.put("url", memuUrl_start+"videos/myImageDetail"+memuUrl_end);
//		sub_buttons.add(repBut6);
		
		Map repBut4 = new HashMap();
		repBut4.put("type", "view");
		repBut4.put("name", "我的头条");
		repBut4.put("url", memuUrl_start+"marrytj/tjCode"+memuUrl_end);
		sub_buttons.add(repBut4);
		
		button1.put("name", "我的头条");
		button1.put("sub_button", sub_buttons);
		buttons.add(button1);
		
		//---------------------------repButs2
		Map button2 = new HashMap();
		
		List<Map> sub_buttons2 = new ArrayList<Map>();
		
//		Map repBut12 = new HashMap();
//		repBut12.put("type", "view");
//		repBut12.put("name", "幸运大转盘");
//		repBut12.put("url", "http://m.haoyicn.cn/cjhqcj/index.html");
//		sub_buttons2.add(repBut12);
		
		Map repBut12 = new HashMap();
		repBut12.put("type", "view");
		repBut12.put("name", "体检套餐卡");
		repBut12.put("url", "http://cn.mikecrm.com/oMsNzX5");
		sub_buttons2.add(repBut12);
		
		Map repBut11 = new HashMap();
		repBut11.put("type", "view");
		repBut11.put("name", "生活服务");
		repBut11.put("url", "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxb8851d53461b983d&redirect_uri=http://marriage.haoyicn.cn/yYBooking/homeCode&response_type=code&scope=snsapi_base&state=1#wechat_redirect");
		sub_buttons2.add(repBut11);
		
		Map repBut13 = new HashMap();
		repBut13.put("type", "view");
		repBut13.put("name", "集体婚礼");
		repBut13.put("url", "http://marriage.haoyicn.cn/game/home");
		sub_buttons2.add(repBut13);
		
		button2.put("name", "生活服务");
		button2.put("sub_button", sub_buttons2);
		buttons.add(button2);
		
		//-JsonMemu
		JSONObject JsonMemu =new JSONObject();
		JsonMemu.put("button", buttons);
		
		String REQUESTCONTENT =JsonMemu.toString();
		
		//请求远端微信Http接口
		byte[] xml = HttpsWenXinUtil.post(requestUrl+=access_token, REQUESTCONTENT, Constants.charset);
		JSONObject JsonObj =new JSONObject().fromObject(new String(xml, Constants.charset));
		System.out.println(JsonObj.toString());
	}
	
	/**
	 * 创建微信菜单
	 * @throws KeyManagementException
	 * @throws NoSuchAlgorithmException
	 * @throws IOException
	 */
	public static void createMenuAiPlus() throws KeyManagementException, NoSuchAlgorithmException, IOException
	{
		String access_token = initWeiXin(Constants.weixinkey.AppID,Constants.weixinkey.AppSecret);
		String requestUrl = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=";
		
		//	http://marriage.cjrbjt.com/marriage/getweixincode
		String memuUrl_start = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxb8851d53461b983d&redirect_uri=http://marriage.haoyicn.cn/";
		String memuUrl_end ="&response_type=code&scope=snsapi_base&state=1#wechat_redirect";
		List<Map> buttons = new ArrayList<Map>();
		
		//---------------------------repButs3
		Map button3 = new HashMap();
		
		List<Map> sub_buttons3 = new ArrayList<Map>();
		
		Map repBut44 = new HashMap();
		repBut44.put("type", "view");
		repBut44.put("name", "最新活动");
		repBut44.put("url", "http://marriage.haoyicn.cn/pubAct/home");
		sub_buttons3.add(repBut44);
		
		Map repBut31 = new HashMap();
		repBut31.put("type", "view");
		repBut31.put("name", "地铁幸福角");
		repBut31.put("url", "http://marriage.haoyicn.cn/cmpAct/home");
		sub_buttons3.add(repBut31);
		
		Map repBut32 = new HashMap();
		repBut32.put("type", "view");
		repBut32.put("name", "会员推荐");
		repBut32.put("url", "http://marriage.haoyicn.cn/xqPubYH/pubMember");
		sub_buttons3.add(repBut32);
		
		button3.put("name", "遇见·交友");
		button3.put("sub_button", sub_buttons3);
		buttons.add(button3);
		
		//---------------------------repButs1
		Map button1 = new HashMap();
		
		List<Map> sub_buttons = new ArrayList<Map>();
		Map repBut4 = new HashMap();
		repBut4.put("type", "view");
		repBut4.put("name", "我的头条");
		repBut4.put("url", memuUrl_start+"marrytj/tjCode"+memuUrl_end);
		sub_buttons.add(repBut4);
		
		Map repBut5 = new HashMap();
		repBut5.put("type", "view");
		repBut5.put("name", "结婚预约");
//		repBut5.put("url", memuUrl_start+"marryreg/marryAgreementCode"+memuUrl_end);
		repBut5.put("url", "http://weixin.hbmzt.gov.cn/hbmz-weixin/hydj/dealpage.jsp");
		
		sub_buttons.add(repBut5);
		
		Map repBut6 = new HashMap();
		repBut6.put("type", "view");
		repBut6.put("name", "婚典商城");
		repBut6.put("url", "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxb8851d53461b983d&redirect_uri=http://marriage.haoyicn.cn/yYBooking/homeCode&response_type=code&scope=snsapi_base&state=1#wechat_redirect");
		sub_buttons.add(repBut6);
		
		button1.put("name", "我要结婚");
		button1.put("sub_button", sub_buttons);
		buttons.add(button1);
		
		//---------------------------repButs2
		Map button2 = new HashMap();
		
		List<Map> sub_buttons2 = new ArrayList<Map>();
		
		Map repBut12 = new HashMap();
		repBut12.put("type", "view");
		repBut12.put("name", "体检套餐卡");
		repBut12.put("url", "http://cn.mikecrm.com/oMsNzX5");
		sub_buttons2.add(repBut12);
		
		Map repBut11 = new HashMap();
		repBut11.put("type", "view");
		repBut11.put("name", "李青说情");
		repBut11.put("url", "http://marriage.haoyicn.cn/game/home");
		sub_buttons2.add(repBut11);
		
		Map repBut13 = new HashMap();
		repBut13.put("type", "view");
		repBut13.put("name", "情感咨询");
		repBut13.put("url", "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxb8851d53461b983d&redirect_uri=http://marriage.haoyicn.cn/yYBooking/homeCode&response_type=code&scope=snsapi_base&state=1#wechat_redirect");
		sub_buttons2.add(repBut13);
		
		button2.put("name", "倾诉热线");
		button2.put("sub_button", sub_buttons2);
		buttons.add(button2);
		
		//-JsonMemu
		JSONObject JsonMemu =new JSONObject();
		JsonMemu.put("button", buttons);
		
		String REQUESTCONTENT =JsonMemu.toString();
		
		//请求远端微信Http接口
		byte[] xml = HttpsWenXinUtil.post(requestUrl+=access_token, REQUESTCONTENT, Constants.charset);
		System.out.println(REQUESTCONTENT);
		JSONObject JsonObj =new JSONObject().fromObject(new String(xml, Constants.charset));
		System.out.println(JsonObj.toString());
	}
	
	/**
	 * 获取OpenId通过oauth2网页认证
	 * @param appid
	 * @param secret
	 * @param code
	 * @param grant_type
	 * @return
	 */
	public static String retOpenId(String code,String AppID,String AppSecret)
	{
		//Step2
		String step2BodyJson = HttpClientUtil.get("https://api.weixin.qq.com/sns/oauth2/access_token?"
				+ "appid="+AppID
				+ "&secret="+AppSecret
				+ "&code="+code
				+ "&grant_type=authorization_code",HTTP.UTF_8);
		
		JSONObject jsobj =new JSONObject().fromObject(step2BodyJson);
		System.out.println("-----"+jsobj.toString());
		String access_token=jsobj.getString("access_token");
		String refresh_token=jsobj.getString("refresh_token");
		String openid=jsobj.getString("openid");
		String scope=jsobj.getString("scope");
		
		return openid;
	}
	
	/**
	 * 返回Oauth2认证过得所有信息
	 * @param code
	 * @param AppID
	 * @param AppSecret
	 * @return
	 */
	public static Map retOauth2Infor(String code,String AppID,String AppSecret)
	{
		Map rep = new HashMap();
		//Step2
		String step2BodyJson = HttpClientUtil.get("https://api.weixin.qq.com/sns/oauth2/access_token?"
				+ "appid="+AppID
				+ "&secret="+AppSecret
				+ "&code="+code
				+ "&grant_type=authorization_code",HTTP.UTF_8);
		
		JSONObject jsobj =new JSONObject().fromObject(step2BodyJson);
		System.out.println("-----"+jsobj.toString());
		String access_token=jsobj.getString("access_token");
		String refresh_token=jsobj.getString("refresh_token");
		String openid=jsobj.getString("openid");
		String scope=jsobj.getString("scope");
		
		rep.put("access_token", access_token);
		rep.put("refresh_token", refresh_token);
		rep.put("openid", openid);
		rep.put("scope", scope);
		
		return rep;
	}
	
	/**
	 * 获取微信用户信息
	 * @param access_token
	 * @param openid
	 * @return
	 */
	public static JSONObject retWeixinUserInfo(String access_token,String openid)
	{
		//获取用户信息
		String bodyJson =HttpClientUtil.get("https://api.weixin.qq.com/cgi-bin/user/info?"
				+ "access_token="+access_token
				+ "&openid="+openid,HTTP.UTF_8);
		
		//转换Json
		JSONObject jsUserObj =new JSONObject().fromObject(bodyJson);
		
		return jsUserObj;
	}
	
	public static void main(String[] args) throws KeyManagementException, NoSuchAlgorithmException, IOException
	{
//		String step2BodyJson = HttpClientUtil.get("https://api.weixin.qq.com/cgi-bin/user/info"
//				+ "?access_token=mSwYR5sWiAPHuCO3BOEgU675B8kb68MIu0idKsqPntghQZD30FHmWyVFfAs0TegxttlIf1wcFufgExmoyqAA4p8opBebaqmklMJBktEMSrVXFSv11HaxMlZ4i3qWigJGGVReAEASHD"
//				+ "&openid=ofwuNsyVHbXdpotCwZ_ZJLp7DSrQ",HTTP.UTF_8);
//		JSONObject jsobj =new JSONObject().fromObject(step2BodyJson);
//		System.out.println(jsobj.get("nickname").toString());
//		
//		System.out.println(jsobj);
		
//		createMenu();
		createMenuAiPlus();
		
		//卡号前9位异或模10取余数，看是否与最后一位相等。
//		String[] strls= new String[9];
//		String printNo="8801403512";
//		for(int i=0;i<printNo.length()-1;i++)
//		{
//			char ss =  printNo.charAt(i);
////			System.out.println(ss);
//			strls[i]=String.valueOf(ss);
//		}
//		
//		int no =Integer.parseInt(strls[0]);
//		for(int i=1;i<strls.length;i++)
//		{
//			System.out.println(no);
//			no = no ^ Integer.parseInt(strls[i]);
//		}
//		System.out.println(no%10);
//		System.out.println(printNo.charAt(9));
	}
}